/**
 * 常用code的生成方法
 * @author 董一华
 * @since 1.00
 * @version 1.00 
 * 
 * 修订列表： v1.00 2009-10-24 
 * 			修订人：董一华 
 * 			修订内容：初始版本 
 */
package com.zjht.gmcc.bean.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Random;

public class MyCode {

	/**
	 * 获取指定长度的随机码(含字母和数字)
	 * @author dyh 2009-10-24
	 * @param f_length
	 * @return
	 */
	public static String getRamCode(int f_length) {
		String f_Randchar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
		String f_Randomizecode = "";
		int f_Random;
		int f_RandLen;
		String[] f_Randchararr = f_Randchar.split(",");
		f_RandLen = f_length; // 定义密码的长度或者是位数
		for (int i = 1; i <= f_RandLen; i++) {
			f_Random = (int) (Math.random() * 21);
			f_Randomizecode = f_Randomizecode + f_Randchararr[f_Random];
		}
		return f_Randomizecode;
	}

	/**
	 * 获取指定长度的随机数字字符串
	 * @author dyh 2009-10-24
	 * @param BitCount 位数
	 * @return 随机数字字符串
	 */
	public static String MyRandomNum(int BitCount) {
		Random random = new Random();
		StringBuilder randomCode = new StringBuilder();
		for (int i = 0; i < BitCount; i++) {
			randomCode.append(random.nextInt(9));
		}
		return randomCode.toString();
	}

	/**
	 * MD5加密
	 * @author dyh 2009-10-24
	 * @param s 要加密的字符串(不可为null)
	 * @return 返回加密后的密文
	 */
	public final static String MD5(String pwd) {
		String Digest = "";
		try {
			MessageDigest currentAlgorithm = MessageDigest.getInstance("md5");
			currentAlgorithm.reset();
			byte[] mess = pwd.getBytes();// 获取要加密的byte数组
			byte[] hash = currentAlgorithm.digest(mess);// 获取加密以后的byte数组
			for (int i = 0; i < hash.length; i++) {
				int v = hash[i];
				if (v < 0) {
					v = 256 + v; // 如果 v < 0 > 0 的数，否则不好转换成字符，哪有ASC代码<0的呀
				}
				if (v < 16) {
					Digest += "0"; // 如果该v<1616进制数就是只有个位，例如15转换就成长度就相等了
				}
				Digest += Integer.toString(v, 16).toUpperCase();
			}
			mess = null;
			hash = null;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return Digest;
	}

	// 获取流水单号
	public static String getTraceCode(String strTraceType, String strOrgaCode) {
		return getTraceCode(strTraceType, strOrgaCode, true, 2, 5);
	}

	/**
	 * 获取流水单号
	 * @author dyh 2010-06-13
	 * @param strTraceType 流水单业务类型
	 * @param strOrgaCode  组织编码
	 * @param hasOrgaCodeInCode 是否在流水单号中添加组织编码
	 * @param yearlen 年份长度(2或4)
	 * @param tracelen 流水长度
	 * @return 流水单号
	 */
	public static String getTraceCode(String strTraceType, String strOrgaCode,
			boolean hasOrgaCodeInCode, int yearlen, int tracelen) {
		String strTraceCode = null;
		if (strTraceType != null && strTraceType.length() <= 4 && strOrgaCode != null
				&& strOrgaCode.length() > 0 && tracelen >= 1 && (yearlen == 2 || yearlen == 4)) {
			MyJDBC myJDBC = null;
			try {
				myJDBC = new MyJDBC();
				strTraceType = strTraceType.toUpperCase();
				String year = MyFormat.getYear(4);
				int traceid = 1;
				String sql = "SELECT traceid FROM OPTRACE WHERE OrgaCode=? AND TraceYear=? AND tracetype=?";
				PreparedStatement ps = myJDBC.prepareStatement(sql);
				ps.setString(1, strOrgaCode);
				ps.setString(2, year);
				ps.setString(3, strTraceType);
				ResultSet rs = ps.executeQuery();
				if (rs.next()) {
					traceid = rs.getInt(1);
				}
				strTraceCode = strTraceType + (hasOrgaCodeInCode ? ("-" + strOrgaCode) : "") + "-"
						+ MyFormat.getYear(yearlen) + MyFormat.getFixedNumber(traceid, tracelen);
				sql = "MERGE INTO OPTRACE a "
						+ "USING (SELECT ? AS orgacode, ? AS tracetype,? AS traceyear FROM DUAL) b "
						+ "ON (a.orgacode = b.orgacode AND a.tracetype = b.tracetype AND a.traceyear=b.traceyear) "
						+ "WHEN MATCHED THEN UPDATE SET a.traceid = a.traceid +1 "
						+ "WHEN NOT MATCHED THEN INSERT (orgacode,traceyear,tracetype,traceid) VALUES(?,?,?,2)";
				ps = myJDBC.prepareStatement(sql);
				ps.setString(1, strOrgaCode);
				ps.setString(2, strTraceType);
				ps.setString(3, year);
				ps.setString(4, strOrgaCode);
				ps.setString(5, year);
				ps.setString(6, strTraceType);
				int flag = ps.executeUpdate();
				if (flag != 1)
					strTraceCode = null;

				return strTraceCode;
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				MyJDBC.close(myJDBC);
			}
		}
		return strTraceCode;
	}

}
